﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LuckDrawSample.Models;

namespace LuckDrawSample.Lib
{
    /// <summary>
    /// 奖品帮助类
    /// </summary>
    public class PrizeHelper
    {
        /// <summary>
        /// 初始化奖品
        /// </summary>
        /// <returns></returns>
        public static List<Prize> InitializePrize()
        {
            return new List<Prize>()
            {
                new Prize()
                {
                    Name = "特等奖",
                    Bonus = (decimal) 666.00,
                    Rate = 0.00005,
                    Quantity = 100,
                },
                new Prize()
                {
                    Name = "一等奖",
                    Bonus = (decimal) 66.00,
                    Rate = 0.0001,
                    Quantity = 200,
                },
                new Prize()
                {
                    Name = "二等奖",
                    Bonus = (decimal) 6.66,
                    Rate = 0.011,
                    Quantity = 22000,
                },
                new Prize()
                {
                    Name = "三等奖",
                    Bonus = (decimal) 1.66,
                    Rate = 0.0435,
                    Quantity = 87000,
                },
                new Prize()
                {
                    Name = "四等奖",
                    Bonus = (decimal) 0.66,
                    Rate = 0.15675,
                    Quantity = 313500,
                },
                new Prize()
                {
                    Name = "五等奖",
                    Bonus = (decimal) 0.36,
                    Rate = 0.5886,
                    Quantity = 1177200,
                },
                new Prize()
                {
                    Name = "谢谢惠顾",
                    Bonus = 0,
                    Rate = 0.2,
                    Quantity = 400000,
                },
            };
        }
        /// <summary>
        /// 重新分配权重(所有)
        /// </summary>
        /// <param name="old"></param>
        /// <param name="indextarget"></param>
        /// <returns></returns>
        public static List<Prize> ReRatePrize(List<Prize> old, int indextarget)
        {
            var oldquantity = new List<Prize>();
            if (indextarget != -1)
            {
                var target = old[indextarget];
                var targetRate = 1 / Convert.ToDouble(target.Quantity) * target.Rate;
                target.Quantity -= 1;
                if (target.Quantity <= 0)
                {
                    old.Remove(target);
                }
                old.Where(y => y != target).ToList().ForEach(x => { oldquantity.Add(new Prize() { Bonus = x.Bonus, Name = x.Name, Quantity = x.Quantity }); });
                if (oldquantity.Any())
                {
                    var quantityValues = oldquantity.Select(x => Convert.ToDouble(x.Quantity)).ToList();
                    var separateVaule = GetSeparateVaule(quantityValues);
                    old.ForEach(x =>
                    {
                        if (x != target)
                        {
                            x.Rate = x.Rate + ReRateValue(Convert.ToDouble(x.Quantity), quantityValues, separateVaule, targetRate);
                        }
                        else
                        {
                            x.Rate = x.Rate - targetRate;
                        }
                    });
                }
            }
            return old;
        }
        /// <summary>
        /// 重分配权重(当前)
        /// </summary>
        /// <param name="thisQuantity"></param>
        /// <param name="allQuantity"></param>
        /// <param name="separateVaule"></param>
        /// <param name="targetRate"></param>
        /// <returns></returns>
        static double ReRateValue(double thisQuantity, List<double> allQuantity, double separateVaule, double targetRate)
        {
            return (GetValueForAll(thisQuantity, allQuantity) * GetValueForMax(thisQuantity, allQuantity) + separateVaule * GetValueForAll(thisQuantity, allQuantity)) * targetRate;
        }
        /// <summary>
        /// 低权重降权
        /// </summary>
        /// <param name="allQuantity"></param>
        /// <returns></returns>
        static double GetSeparateVaule(List<double> allQuantity)
        {
            return allQuantity.Sum(x => GetValueForAll(x, allQuantity) - GetValueForAll(x, allQuantity) * GetValueForMax(x, allQuantity));
        }
        /// <summary>
        /// 获取权重比(所有)
        /// </summary>
        /// <param name="thisQuantity"></param>
        /// <param name="allQuantity"></param>
        /// <returns></returns>
        static double GetValueForAll(double thisQuantity, List<double> allQuantity)
        {
            return thisQuantity / allQuantity.Sum();
        }
        /// <summary>
        /// 获取权重比(最大)
        /// </summary>
        /// <param name="thisQuantity"></param>
        /// <param name="allQuantity"></param>
        /// <returns></returns>
        static double GetValueForMax(double thisQuantity, List<double> allQuantity)
        {
            return thisQuantity / allQuantity.Max();
        }
    }
}
